package com.ht.aems.fesservice;

import com.ht.aems.fesmodel.PointManager;
import com.ht.aems.fesmodel.RtMeasureQuery;
import com.ht.aems.fesmodel.RtMeasureSaver;
import com.ht.aems.fesmodel.data.*;
import com.ht.aems.fesmodel.persist.RtMeasureHandler_Map;
import com.ht.aems.fesservice.impl.PointRepeator_sh;
import com.ht.aems.util.ObjectBuffer;
import rtdb.RtMeasureHandler_MemoCached;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


/**
 * Created by IntelliJ IDEA.
 *
 * @author Dong Shufeng
 *         Date: 2008-7-31
 */
public class RtuDataDealer extends Thread {

    private ObjectBuffer ycBuffer = new ObjectBuffer(50);
    private ObjectBuffer yxBuffer = new ObjectBuffer(500);
//    private ObjectBuffer soeBuffer = new ObjectBuffer(500);
    private ObjectBuffer changeYxBuffer = new ObjectBuffer(200);
    private boolean isStop = false;
    private RtMeasureSaver persist = new RtMeasureHandler_MemoCached();
    private RtMeasureSaver persist2 = new RtMeasureHandler_Map();
    private RtMeasureQuery valueMap = (RtMeasureQuery) persist2;
    private RtMeasureQuery rtMeasureQuery = (RtMeasureQuery) persist;
//    private MeasPersistence soePersit = new MeasSqlPersist();
    private PointRepeator repeator = new PointRepeator_sh();
    private HashMap<Integer, Integer> realTimeYX = new HashMap<Integer, Integer>();

    private static RtuDataDealer instance = new RtuDataDealer();

    public static RtuDataDealer getInstance() {
        if (instance != null) {
            return instance;
        }
        return null;
    }

    private RtuDataDealer() {
        super();
    }

    @Override
    public void run() {
        while (!isStop) {
            try {
                doWork();
                sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void doWork() {
        Object[] ycs = ycBuffer.read();
        if (ycs != null && ycs.length > 0) {
            YCData[] toSave = new YCData[ycs.length];
            System.arraycopy(ycs, 0, toSave, 0, ycs.length);
            persist2.saveYCs(toSave);
            persist.saveYCs(toSave);
            int toTransNum = 0;
            for (Object obj : ycs) {
                YCData yc = (YCData) obj;
                for (int ycBit : yc.getYcBit()) {
                    AnalogPoint p = PointManager.getInstance().getAnalogPoint(yc.getRemoteUnitId(), ycBit);
                    if (p == null || p.getTransmitToId() == null || p.getTransmitToId().trim().equals(""))
                        continue;
                    toTransNum++;
                }
            }
            if (toTransNum > 0) {
                List<AnalogPoint> toTransmitPoints = new ArrayList<AnalogPoint>(toTransNum);
                for (Object obj : ycs) {
                    YCData yc = (YCData) obj;
                    for (int i = 0; i < yc.getData().length; i++) {
                        AnalogPoint p = PointManager.getInstance().getAnalogPoint(yc.getRemoteUnitId(), yc.getYcBit()[i]);
                        if (p == null || p.getTransmitToId() == null || p.getTransmitToId().trim().equals(""))
                            continue;
                        p.setEngValue(yc.getData()[i]);
                        toTransmitPoints.add(p);
                    }
                }
                repeator.doRepeat(toTransmitPoints.toArray(new AnalogPoint[]{}));
            }
        }

        Object[] yxs = yxBuffer.read();
        if (yxs != null && yxs.length > 0) {
            YXData[] toSave = new YXData[yxs.length];
            System.arraycopy(yxs, 0, toSave, 0, yxs.length);
            persist2.saveYXs(toSave);
            persist.saveYXs(toSave);
            int toTransNum = 0;
            for (Object obj : yxs) {
                YXData yx = (YXData) obj;
                for (int yxBit : yx.getYxBit()) {
                    DiscretePoint p = PointManager.getInstance().getDiscretePoint(yx.getRemoteUnitId(), yxBit);
                    if (p == null || p.getTransmitToId() == null || p.getTransmitToId().trim().equals(""))
                        continue;
                    toTransNum++;
                }
            }
            if (toTransNum > 0) {
                List<DiscretePoint> toTransmitPoints = new ArrayList<DiscretePoint>(toTransNum);
                for (Object obj : yxs) {
                    YXData yx = (YXData) obj;
                    for (int i = 0; i < yx.getData().length; i++) {
                        DiscretePoint p = PointManager.getInstance().getDiscretePoint(yx.getRemoteUnitId(), yx.getYxBit()[i]);
                        if (p == null || p.getTransmitToId() == null || p.getTransmitToId().trim().equals(""))
                            continue;
                        p.setEngValue(yx.getData()[i]);
                        toTransmitPoints.add(p);
                    }
                }
                repeator.doRepeat(toTransmitPoints.toArray(new DiscretePoint[]{}));
            }
        }
//        Object[] soes = soeBuffer.read();
//        if (soes != null && soes.length > 0) {
//            SOEData[] toSave = new SOEData[soes.length];
//            System.arraycopy(soes, 0, toSave, 0, soes.length);
//            soePersit.saveSOEs(toSave);
//        }

        Object[] changeYxs = changeYxBuffer.read();
        if (changeYxs != null && changeYxs.length > 0) {
            YXData[] toSave = new YXData[changeYxs.length];
            System.arraycopy(changeYxs, 0, toSave, 0, changeYxs.length);
            Sampler.sampleChangeYx(toSave);
        }
    }

    public ObjectBuffer getYcBuffer() {
        return ycBuffer;
    }

    public ObjectBuffer getYxBuffer() {
        return yxBuffer;
    }

//    public ObjectBuffer getSoeBuffer() {
//        return soeBuffer;
//    }

    public boolean isStop() {
        return isStop;
    }

    public void setStop(boolean stop) {
        isStop = stop;
    }

    public RtMeasureQuery getValueMap() {
        return valueMap;
    }

    public RtMeasureQuery getRtMeasureQuery() {
        return rtMeasureQuery;
    }

    public ObjectBuffer getChangeYxBuffer() {
        return changeYxBuffer;
    }

    public Integer getRealTimeYXValue(int rtuId, int pointNum) {
        return realTimeYX.get(MeasurePoint.getNID(rtuId, pointNum));
    }

    public void setRealTimeYXValue(int rtuId, int pointNum, int value) {
        realTimeYX.put(MeasurePoint.getNID(rtuId, pointNum), value);
    }
}
